/*This file is part of AENIMA. AENIMA is a module of BCI++ framework for the implementation of brain computerinterface systems. 
AEnima is intended for use with BCI++ only.

BCI++ is a project of the Sensibilab of the Politecnico di Milano. 

AENIMA is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as 
published by the Free Software Foundation, either version 3 of 
the License, or (at your option) any later version.

AENIMA is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU General Public License
and the GNU Lesser General Public License along with AENIMA.  
If not, see <http://www.gnu.org/licenses/>.*/

/*!
	\file	ProtocolMngr.h
	 This file contains ProtocolMngr class. 

	\author	Sensibilab EMail: info.sensibilab@polimi.it

	\date	2007-09-06 creation \n
		2009-01-27 last modification

	\b COPYRIGHT: 
		This program is property of Sensibilab - Campus Ponit - Lecco
*/
#pragma once

#include "Constants.h"
#include <irrlicht.h>
#include <iostream>
#include "SocketComm_base.h"
#include "LedDriver_base.h"
#include "structs\BCIMessage.h"
#include "SoundSystem_base.h"
#include "GraphicEngine_base.h" // GRAPHICENGINE SEMPRE IN FONDO
#include "typedef.h"
#include "DealProtType.h"
using namespace std;
using namespace irr;


#pragma comment(lib, "Irrlicht.lib")

//Const for SetNextOpt
const int NOTHING=0;
const int CHANGE=1;
const int LEDON=2;
const int WAITING=3;
const int START=4;
const int ANIMWAIT=5;
const int MI_EPOCHS	= 60;


class DealProtType;

/*!\class GraphicEngine_base
This is the father class for all the portocols.*/
class ProtocolMngr
{
public:
	// BASIC MEMBERS
	ProtocolMngr(GraphicEngine_base *Engine, SoundSystem_base* Sound, SocketComm_base* pSocket, LedDriver_base* myLed, bool startup, DealProtType *pParent);
	~ProtocolMngr(void);
	
	public:
	// BASIC MEMBERS
	GraphicEngine_base *AEngine;
	SoundSystem_base *MainSound;
	SocketComm_base*	pSocket;
	LedDriver_base *myStimuli;
	bool StartUP;
	int MyTimer;//ITimer* MyTimer; // Protocol Timer
	int ProtXCursor;
	int tZero;		 // Time-Zero
	int ProtXState; // Protocol Current State
	/*!This flag says if the protocol is active (true) or not (false)*/
	bool isRunning; // is Protocol Running?
	bool isWaiting;
	bool isFade;
	bool DoStopMusic,DoPlayMusic;
	float x,y,z;
	core::vector3df pos;
	SEvent	event;
	bool EnableDomos;


	scene::ISceneNode*	mySceneNode;
	scene::IAnimatedMesh* myMesh;
	gui::IGUIImage* myImage;
	DealProtType *dealProtocol;
	operation nextOpt;
	scene::IAnimatedMeshSceneNode* myAnimatedMesh;
	scene::ISceneNodeAnimator* myAnimator;
	
	int GetXState(void);
	
	/*!\fn void EvalProt(void)
	This method is a function automatically called by GigaLoop in the main file. It is used to evaluate the protocol: the function update the timer value and call myProtocol method.*/
	void EvalProt(void);

	void RunIntoWhile(void);
	
	/*!\fn void ResetTime(void)
	This functin can be used to reset the timer. The tZero variable is set to the current time. */
	void ResetTime(void);
	
	/*!\fn void SetNextCall(int Millis)
	This fuction sets the tZero variable so that it is possible to apply a fixed delay.
	\param Millis Delay in milliseconds.*/
	void SetNextCall(int Millis);

	/*!\fn void SendBCIMessage (int Kind,   int Value = 0,   int * pBuffer = 0,   int BuffSize = 0)
	This function has been developed in order to send message to the Hardware Interface Module.*/
	void SendBCIMessage(int Kind, int Value=0, int *pBuffer=0,int BuffSize=0);
	
	/*!\fn void setNextOpt (int kind, int delay, int p1=0, char *ptext=NULL)
	This function is used in some protocol to select the operation to do after a fixed delay. The possible operations are placed into the myProtocol function and are called diferently using a switch/case method. The flag are set into Constants.h by define NAME VALUE.\n
	The operation implemented in some porotocol are, for examples:\n
	NOTHING=0;\n
	CHANGE=1 To change protocol;\n
	LEDON=2 To turn off leds;\n
	WAITING=3 To turn on leds;\n
	START=4 To start protocol after a countdown of 5 seconds. This is used in SSVEP_Games.*/
	void setNextOpt (int kind, int delay, int p1=0, char *ptext=NULL);
	
	/*!\fn void SendStart(void)
	Request to HIM to start the acquisition. If HIM replys with CONNECTIONCOMPLETD, AEnima call StratProt.*/  
	void SendStart(void);
	
	/*!\fn	void RequestParams(void)
	This function is usuful to request to HIM some parameters like stimulation frequencies, etc.*/
	void RequestParams(void);
	
	/*!\fn void OnNew(void)
	This function unloads the old protocol/scene, load new resources and fades the visualizzation of the new protocol. 
	With the Override of the function ProtocolMngr::LoadResources() it is possible to force the loading of resources of the specific protocol. 
	The execution of this function is masked by a "LOADING" message. */
	void OnNew(void);

	// CUSTOM MEMBERS
	
	/*!\fn virtual bool StopProt(bool SendSocketMsg = true)
	Virtual function for stoping protocols. The flag isRunning is set false and a BCI_Message in order 
	to stop acquisition is sent to the Hardware Interface Module. This function also can stop the 
	stimulators (if necessary) and hide the graphic object.
	\param SendSocketMsg Is a flag that is true if the softwere have to sent a stop acquisition message to the HIM.*/
	virtual bool StopProt(bool SendSocketMsg = true);
	
	/*!\fn virtual bool StartProt(bool SendSocketMsg = true)
	Vistual function for the starting of protocols. This function sends a BCI_Message to the 
	Hardware Interface Module that will start the acquisition, turn on the stimulator (if necessary)
	and reset timer. This function sets also the flag isRunning = true. */
	virtual bool StartProt(bool SendSocketMsg = true);
	
	/*!\fn 	virtual void myProtocol(int myTime)
	You can use this function in order to add code that must be run automatically and continuosly (see example).*/
	virtual void myProtocol(int myTime);
	
	/*!\fn 	virtual void RunIntoWhile(void)
	You can use this function in order to add code that must be run automatically and continuosly in the while cycle between beginscene and endscene.*/
	virtual void myRunIntoWhile(void);
	
	/*!\fn virtual void OnProtocolEvent(void)
	This is a virtual function that can be used to manage events directly generate by the software.*/
	virtual void OnProtocolEvent(void);
	
	/*!\fn	virtual bool OnSocketEvent(BCIMessage *SocketMsg)
	This is a virtual function that can be used to manage events generated by socket. \n
	The method OnSocketEvent in ProtocolMngr calls:\n
	OnClassification(BCIMessage) if the BCIMessage is a CLASSIFICATION kind\n
	OnFeedback(BCIMessage) if the BCIMessage is a FEEDBACK kind\n
	StartProt(bool) if the BCIMessage is a CONNECTION_COMPLETED kind\n
	OnSetParams(BCIMessage) if the BCIMessage is a SET_PARAMS kind*/
	virtual bool OnSocketEvent(BCIMessage *SocketMsg);
	
	/*!\fn virtual void LoadResources(void)
	Virtual function for the loading of the resources of any protocol. In this function you can also do heavy startup. LoadResources is directly used by ProtocolMngr::OnNew() that unloads the old protocol/scene and load new resoureces. While this function works, on the screen is shown a "LOADING" message. */
	virtual void LoadResources(void);
	
	/*!\fn virtual void OnClassification(BCIMessage *SocketMsg)
	You can use this function to manage classification data from Hardware Module Interface.*/
	virtual void OnClassification(BCIMessage *SocketMsg);
	
	/*!\fn virtual void OnFeedback (BCIMessage *SocketMsg)
	In this function you must add the cade to manage ypur feedback.*/
	virtual void OnFeedback (BCIMessage *SocketMsg);
	
	/*!\fn virtual void OnSetParams (BCIMessage *SocketMsg)
	This function is called when a BCIMessage SETPARAMS kind is received. You can set here for example your stimulator frequencies.*/
	virtual void OnSetParams (BCIMessage *SocketMsg);
	
	/*!\fn virtual void HideCenter(void)
	This function hides the center cursor.*/
	virtual void HideCenter(void);
	
	/*!\fn virtual void RotAnimator(char *NodeName, scene::ISceneNodeAnimator* anim)
	Function to create a rotating animation of a sceneNode.*/
	virtual void RotAnimator(char *NodeName, scene::ISceneNodeAnimator* anim);
	
	/*!\fn	virtual void MoveAnimator(char *NodeName, float x, float y, float z, int time)
	This functin create a movement animation of the "NodeName" sceneNode of a duration "time" in the direction and of the distance set by "x,y,z". */
	virtual void MoveAnimator(char *NodeName, float x, float y, float z, int time);
	
	/*!\fn virtual void ViewFeedback(void)
	This function is useful to show on the screen the feedback bars.*/
	virtual void ViewFeedback(void);
	
	/*!\fn virtual void HideFeedback(void)
	This function is useful to hide the feedback bars.*/
	virtual void HideFeedback(void);
	
	/*!\fn virtual void ViewCenter(void)
	This function show the central cursor on screen.*/
	virtual void ViewCenter(void);
	
	/*!\fn virtual void KeyEvent(const SEvent &event)
	This  is a method that allow to associate a specific function to a key. 
	When the key is pressed, the eventReceiver class call automatically this 
	method and control what key has been pressed. */
	virtual void KeyEvent(const SEvent &event);

	virtual bool OnGuiEvent(const SEvent &event);
	virtual void OtherEvent(const SEvent &event);
};



